import { initBuffers } from "./init-buffers.js";
import { drawScene } from "./draw-scene.js";

function main() {
    const canvas = document.querySelector("#glcanvas");
    const gl = canvas.getContext("webgl");//初始化webgl上下文

    if (gl === null) {
        alert(
            "Unable to initialize WebGL. Your browser or machine may not support it."
        );
        return;
    }

    // Set clear color to black, fully opaque
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    // Clear the color buffer with specified clear color
    gl.clear(gl.COLOR_BUFFER_BIT);

    /**
        * @variation {string} vsSource
        * @variation {string} fsSource
        * @variation {string} shaderProgram 着色器程序
        * @variation {string} programInfo
        * @variation {string} aVertexPosition 顶点位置值
        * @variation {string} uModelMatrix 4*4矩阵
        * @variation {string} gl_Position 由 GLSL 提供的特殊变量
        * @variation {string} gl_FragColor 颜色存储的特殊变量
    */
    const vsSource = `
        attribute vec4 aVertexPosition;
        uniform mat4 uModelViewMatrix;
        uniform mat4 uProjectionMatrix;
        void main() {
            gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
        }
    `;

    const fsSource = `
        void main() {
            gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
        }
    `;

    const shaderProgram = initShaderProgram(gl, vsSource, fsSource);

    const programInfo = {
        program: shaderProgram,
        attribLocations: {
            vertexPosition: gl.getAttribLocation(shaderProgram, "aVertexPosition"),
        },
        uniformLocations: {
            projectionMatrix: gl.getUniformLocation(
                shaderProgram,
                "uProjectionMatrix"
            ),
            modelViewMatrix: gl.getUniformLocation(shaderProgram, "uModelViewMatrix"),
        },
    };

    const buffers = initBuffers(gl);

    drawScene(gl, programInfo, buffers);//绘制背景
}

/**
 * @description 初始化着色器程序，让webgl绘制数据
*/
function initShaderProgram(gl, vsSource, fsSource) {
    const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
    const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);

    const shaderProgram = gl.createProgram();//创建着色器程序
    gl.attachShader(shaderProgram, vertexShader);
    gl.attachShader(shaderProgram, fragmentShader);
    gl.linkProgram(shaderProgram);

    if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {//判断是否创建成功
        alert(
            `Unable to initialize the shader program: ${gl.getProgramInfoLog(
                shaderProgram
            )}`
        );
        return null;
    }

    return shaderProgram;
}

/**
 * @description 将 WebGL 上下文，着色器类型和源码作为参数输入，创建指定类型的着色器，上传 source 源码并编译
 * @param {object} gl webgl上下文
 * @param {string} type 着色器的类型
 * @param {string} source 源码
 */
function loadShader(gl, type, source) {
    const shader = gl.createShader(type);//根据着色器类型创建一个新的着色器
    gl.shaderSource(shader, source);//将源码发送到着色器
    gl.compileShader(shader);//着色器获取到源代码后，编译着色器
    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {//判断是否成功编译着色器
        //通过gl.getShaderParameter(着色器，要检查的参数)获得gl.COMPILE_STATUS的值
        alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
        // 通过gl.getShaderInfoLog(着色器)获取日志信息
        gl.deleteShader(shader);//删除着色器
        return null;
    }

    return shader;
}

